home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2001 May / SGI Freeware 2001 May - Disc 3.iso / dist / fw_expect.idb / usr / freeware / bin / xkibitz.z / xkibitz
Text File  |  1999-01-26  |  4KB  |  209 lines

  1. #!/usr/freeware/bin/expect --
  2.  
  3. # share an xterm with other users
  4. # See xkibitz(1) man page for complete info.
  5. # Compare with kibitz.
  6. # Author: Don Libes, NIST
  7. # Version: 1.2
  8.  
  9. proc help {} {
  10.     puts "Commands          Meaning"
  11.     puts "--------          -------"
  12.     puts "return            return to program"        
  13.     puts "=                 list"
  14.     puts "+ <display>       add"
  15.     puts "- <tag>           drop"
  16.     puts "where <display> is an X display name such as nist.gov or nist.gov:0.0"
  17.     puts "and <tag> is a tag from the = command."
  18.     puts "+ and - require whitespace before argument."
  19.     puts {return command must be spelled out ("r", "e", "t", ...).}
  20. }
  21.  
  22. proc prompt1 {} {
  23.     return "xkibitz> "
  24. }
  25.  
  26. proc h {} help
  27. proc ? {} help
  28.  
  29. # disable history processing - there seems to be some incestuous relationship
  30. # between history and unknown in Tcl 8.0
  31. proc history {args} {}
  32. proc unknown {args} {
  33.     puts "$args: invalid command"
  34.     help
  35. }
  36.  
  37. set tag2pid(0)            [pid]
  38. set pid2tty([pid])        "/dev/tty"
  39. if [info exists env(DISPLAY)] {
  40.     set pid2display([pid])    $env(DISPLAY)
  41. } else {
  42.     set pid2display([pid])    ""
  43. }
  44.  
  45. # small int allowing user to more easily identify display
  46. # maxtag always points at highest in use
  47. set maxtag 0
  48.  
  49. proc + {display} {
  50.     global ids pid2display pid2tag tag2pid maxtag pid2sid
  51.     global pid2tty env
  52.  
  53.     if ![string match *:* $display] {
  54.         append display :0.0
  55.     }
  56.  
  57.     if {![info exists env(XKIBITZ_XTERM_ARGS)]} {
  58.         set env(XKIBITZ_XTERM_ARGS) ""
  59.     }
  60.  
  61.     set dummy1 [open /dev/null]
  62.     set dummy2 [open /dev/null]
  63.     spawn -pty -noecho
  64.     close $dummy1
  65.     close $dummy2
  66.  
  67.     stty raw -echo < $spawn_out(slave,name)
  68.     # Linux needs additional stty, sounds like a bug in its stty to me.
  69.     # raw should imply this stuff, no?
  70.     stty -icrnl -icanon < $spawn_out(slave,name)
  71.  
  72.     regexp ".*(.)(.)" $spawn_out(slave,name) dummy c1 c2
  73.     if {[string compare $c1 "/"] == 0} {
  74.         # On Pyramid and AIX, ttynames such as /dev/pts/1
  75.         # requre suffix to be padded with a 0
  76.         set c1 0
  77.     }
  78.  
  79.     set pid [eval exec xterm \
  80.             -display $display \
  81.             -geometry [stty columns]x[stty rows] \
  82.             -S$c1$c2$spawn_out(slave,fd) \
  83.                         $env(XKIBITZ_XTERM_ARGS) &]
  84.     close -slave
  85.  
  86.     # xterm first sends back window id, discard
  87.     log_user 0
  88.     expect {
  89.         eof {wait;return}
  90.         \n
  91.     }
  92.     log_user 1
  93.  
  94.     lappend ids $spawn_id
  95.     set pid2display($pid) $display
  96.     incr maxtag
  97.     set tag2pid($maxtag) $pid
  98.     set pid2tag($pid) $maxtag
  99.     set pid2sid($pid) $spawn_id
  100.     set pid2tty($pid) $spawn_out(slave,name)
  101.     return
  102. }
  103.  
  104. proc = {} {
  105.     global pid2display tag2pid pid2tty
  106.  
  107.     puts "Tag  Size Display"
  108.     foreach tag [lsort -integer [array names tag2pid]] {
  109.         set pid $tag2pid($tag)
  110.         set tty $pid2tty($pid)
  111.         
  112.         puts [format "%3d [stty columns < $tty]x[stty rows < $tty] $pid2display($pid)" $tag]
  113.     }
  114. }
  115.  
  116. proc - {tag} {
  117.     global tag2pid pid2tag pid2display maxtag ids pid2sid
  118.     global pid2tty
  119.  
  120.     if ![info exists tag2pid($tag)] {
  121.         puts "no such tag"
  122.         return
  123.     }
  124.     if {$tag == 0} {
  125.         puts "cannot drop self"
  126.         return
  127.     }
  128.  
  129.     set pid $tag2pid($tag)
  130.  
  131.     # close and remove spawn_id from list
  132.     set spawn_id $pid2sid($pid)
  133.     set index [lsearch $ids $spawn_id]
  134.     set ids [lreplace $ids $index $index]
  135.  
  136.     exec kill -9 $pid
  137.     close
  138.     wait
  139.  
  140.     unset tag2pid($tag)
  141.     unset pid2tag($pid)
  142.     unset pid2display($pid)
  143.     unset pid2sid($pid)
  144.     unset pid2tty($pid)
  145.  
  146.     # lower maxtag if possible
  147.     while {![info exists tag2pid($maxtag)]} {
  148.         incr maxtag -1
  149.     }
  150. }
  151.  
  152. exit -onexit {
  153.     unset pid2display([pid])    ;# avoid killing self
  154.  
  155.     foreach pid [array names pid2display] {
  156.         catch {exec kill -9 $pid}
  157.     }
  158. }
  159.  
  160. trap exit HUP
  161.  
  162. trap {
  163.     set r [stty rows]
  164.     set c [stty columns]
  165.     stty rows $r columns $c < $app_tty
  166.     foreach pid [array names pid2tty] {
  167.         if {$pid == [pid]} continue
  168.         stty rows $r columns $c < $pid2tty($pid)
  169.     }
  170. } WINCH
  171.  
  172. set escape \035        ;# control-right-bracket
  173. set escape_printable "^\]"
  174.  
  175. while [llength $argv]>0 {
  176.     set flag [lindex $argv 0]
  177.     switch -- $flag \
  178.     "-escape" {
  179.         set escape [lindex $argv 1]
  180.         set escape_printable $escape
  181.         set argv [lrange $argv 2 end]
  182.     } "-display" {
  183.         + [lindex $argv 1]
  184.         set argv [lrange $argv 2 end]
  185.     } default {
  186.         break
  187.     }
  188. }
  189.  
  190. if [llength $argv]>0 {
  191.     eval spawn -noecho $argv
  192. } else {
  193.     spawn -noecho $env(SHELL)
  194. }
  195. set prog $spawn_id
  196. set app_tty $spawn_out(slave,name)
  197.  
  198. puts "Escape sequence is $escape_printable"
  199.  
  200. interact {
  201.     -input $user_spawn_id -reset $escape {
  202.         puts "\nfor help enter: ? or h or help"
  203.         interpreter
  204.     } -output $prog
  205.     -input ids -output $prog
  206.     -input $prog -output $user_spawn_id -output ids
  207. }
  208.  
  209.